﻿//Created by Action Script Viewer - http://www.buraks.com/asv
package reprise.commands {
    import flash.events.*;
    import reprise.events.*;
    import reprise.data.collection.*;

    public class CompositeCommand extends AbstractAsynchronousCommand {

        protected var m_prioritiesInvalid:Boolean;
        protected var m_isExecutingAsynchronously:Boolean;
        protected var m_currentCommands:IndexedArray;
        protected var m_numCommandsExecuted:int;
        protected var m_abortOnFailure:Boolean = true
        protected var m_nextResourceId:int;
        protected var m_maxParallelExecutionCount:int = 1
        protected var m_pendingCommands:IndexedArray;
        protected var m_numCommandsFailed:int;

        public function CompositeCommand(){
            reset();
        }
        public function setMaxParallelExecutionCount(_arg1:int):void{
            m_maxParallelExecutionCount = _arg1;
            if (m_isExecuting){
                executeNext();
            };
        }
        protected function command_complete(_arg1:CommandEvent):void{
            var _local2:IAsynchronousCommand = IAsynchronousCommand(_arg1.target);
            unregisterListenersForAsynchronousCommand(_local2);
            m_currentCommands.remove(_arg1.target);
            m_numCommandsExecuted++;
            if (!_local2.didSucceed()){
                m_didSucceed = false;
                m_numCommandsFailed++;
                if (m_abortOnFailure){
                    failGracefully(false);
                    return;
                };
            };
            executeNext();
        }
        protected function failGracefully(_arg1:Boolean):void{
            var _local3:ICommand;
            var _local2:int = m_currentCommands.length;
            while (_local2--) {
                _local3 = ICommand(m_currentCommands[_local2]);
                if (commandExecutesAsynchronously(_local3)){
                    unregisterListenersForAsynchronousCommand(IAsynchronousCommand(_local3));
                    IAsynchronousCommand(_local3).cancel();
                };
            };
            if (_arg1){
                super.cancel();
            } else {
                notifyComplete(m_didSucceed);
            };
        }
        public function executesAsynchronously():Boolean{
            return (m_isExecutingAsynchronously);
        }
        protected function executeNext():void{
            if ((((m_pendingCommands.length == 0)) && ((m_currentCommands.length == 0)))){
                m_isExecuting = false;
                if (m_isExecutingAsynchronously){
                    notifyComplete(m_didSucceed);
                };
                return;
            };
            if ((((((((m_currentCommands.length >= m_maxParallelExecutionCount)) && ((m_maxParallelExecutionCount > 0)))) || (!(m_pendingCommands.length)))) || (m_isCancelled))){
                return;
            };
            if (m_prioritiesInvalid){
                m_pendingCommands.sortOn(["priority", "id"], [(Array.NUMERIC | Array.DESCENDING), Array.NUMERIC]);
                m_prioritiesInvalid = false;
            };
            var _local1:ICommand = ICommand(m_pendingCommands.shift());
            if ((((_local1 is IAsynchronousCommand)) && (IAsynchronousCommand(_local1).isCancelled()))){
                executeNext();
                return;
            };
            if (commandExecutesAsynchronously(_local1)){
                registerListenersForAsynchronousCommand(IAsynchronousCommand(_local1));
                m_currentCommands.push(_local1);
                _local1.execute();
            } else {
                _local1.execute();
                m_numCommandsExecuted++;
                if (!_local1.didSucceed()){
                    m_numCommandsFailed++;
                    m_didSucceed = false;
                    if (m_abortOnFailure){
                        failGracefully(false);
                        return;
                    };
                };
            };
            executeNext();
        }
        public function abortOnFailure():Boolean{
            return (m_abortOnFailure);
        }
        public function invalidatePriorities():void{
            m_prioritiesInvalid = true;
        }
        public function numFailedCommands():int{
            return (m_numCommandsFailed);
        }
        public function setAbortOnFailure(_arg1:Boolean):void{
            m_abortOnFailure = _arg1;
        }
        public function length():uint{
            if (!m_pendingCommands){
                return (0);
            };
            return ((m_pendingCommands.length + m_currentCommands.length));
        }
        public function removeCommand(_arg1:ICommand):void{
            if (m_currentCommands.objectExists(_arg1)){
                return;
            };
            m_pendingCommands.remove(_arg1);
        }
        public function addCommand(_arg1:ICommand):void{
            if (((!(m_isExecuting)) && (!(m_pendingCommands.length)))){
                reset();
            };
            m_isExecutingAsynchronously = ((m_isExecutingAsynchronously) || (commandExecutesAsynchronously(_arg1)));
            _arg1.id = m_nextResourceId++;
            _arg1.setQueueParent(this);
            m_pendingCommands.push(_arg1);
            if (m_isExecuting){
                executeNext();
            };
        }
        public function numExecutedCommands():int{
            return (m_numCommandsExecuted);
        }
        override public function reset():void{
            m_pendingCommands = new IndexedArray();
            m_currentCommands = new IndexedArray();
            m_isExecutingAsynchronously = false;
            m_didSucceed = true;
            m_nextResourceId = 0;
            m_numCommandsExecuted = 0;
            m_numCommandsFailed = 0;
            super.reset();
        }
        override public function execute(... _args):void{
            if (m_isExecuting){
                return;
            };
            super.execute();
            executeNext();
        }
        protected function registerListenersForAsynchronousCommand(_arg1:IAsynchronousCommand):void{
            _arg1.addEventListener(Event.COMPLETE, command_complete);
            _arg1.addEventListener(Event.CANCEL, command_cancel);
        }
        override public function cancel():void{
            failGracefully(true);
        }
        protected function command_cancel(_arg1:CommandEvent):void{
            var _local2:Event = new (_arg1 as Object).constructor(Event.COMPLETE, true);
            IAsynchronousCommand(_arg1.target).dispatchEvent(_local2);
            m_numCommandsExecuted--;
        }
        protected function commandExecutesAsynchronously(_arg1:ICommand, ... _args):Boolean{
            var _local3 = (_arg1 is IAsynchronousCommand);
            if ((_arg1 as Object).hasOwnProperty("executesAsynchronously")){
                _local3 = ((_arg1["executesAsynchronously"] is Function)) ? _arg1["executesAsynchronously"]() : _arg1["executesAsynchronously"];
            };
            return (_local3);
        }
        protected function unregisterListenersForAsynchronousCommand(_arg1:IAsynchronousCommand):void{
            _arg1.removeEventListener(Event.COMPLETE, command_complete);
            _arg1.removeEventListener(Event.CANCEL, command_cancel);
        }

    }
}//package reprise.commands 
